text:
layout: post
title: "텔레그램(Telegram) CLI 통해서 가지고 놀기 with BotApi"
description: ""
categories : development
sub_categories : ""
date: 2016-01-19
tags: ['API', 'CLI', 'telegram', '개념', '리눅스', '명령어', '봇', '서버', '소개', '영문', '우분투', '유닉스', '텔레그램', '한글', '한글화']
comments: true
share: true
---

메신저 중에 하나로 텔레그램을 이용하고있습니다. 텔레그램은 장점이 매우 많습니다. 텔레그램은
Github('git@github.com:vysheng/tg.git') 통해서 API 및 소스가 공개하고있습니다. 해당 자료 다운 받으시면
됩니다.

우선 텔레그램의 주요 특징과 장점들에 대해 간략하게 적었습니다.(이미 너무나 잘 알고있다면 스킵하셔도 좋습니다.)

  1. **Private **(Telegram messages are heavily encrypted and can self-destruct.)
  2. **Cloud-Based** (Telegram lets you access your messages from multiple devices.)
  3. **Fast** (Telegram delivers messages faster than any other application.)
  4. **Distributed** (Telegram servers are spread worldwide for security and speed.)
  5. **Open** (Telegram has an open API and protocol free for everyone.)
  6.   7. **Free** (Telegram is free forever. No ads. No subscription fees.)
  8. **Secure **(Telegram keeps your messages safe from hacker attacks.)
  9. **Powerful **(Telegram has no limits on the size of your media and chats.)

이 것 이외에도 프로그래머라면 디버깅할 때, 정말 도움이 많이 됩니다.

또한 cron설정을 통해서 주기적으로 스냅샷 정보 또는 서버 상태등을 피드백 받을수있어 더 좋습니다.

이러한 장점들을 보니 얼른 설치하고싶다구요? 저의 간략한 환경(Description: Ubuntu 14.04.2 LTS) 입니다. 따라하실때
참고하세요 ^^..

또 설치하기전에 가상번호를 이용하는 방법도있고 위에 말한 장점들을 사용할 때 계정을 이용하지아니하고 봇을 이용하는 방법이있는데, 본인은 봇을
이용하는 방법을 선택하겠다. 이 방법이 훨씬 간단하고 효율적일 것 같아서다. 봇 이용방법 이외 Cli를 통한 Telegram 사용방법도
기재할테니 Cli를 통한 사용법이 알고싶은 분들은 봇을 통한 이용방법 부분은 건너뛰시면 되겠습니다.

아래는 텔레그램 bot api 관련 페이지입니다. (https://core.telegram.org/bots/api)

봇에 대한 자세한 설명은 해당 링크('https://core.telegram.org/bots')를 참조하시길 바랍니다.

![](/assets/images/posts/490/2616B83F569DFD501F2C03.PNG)

BotFather을 통하여 나의 새로운 봇을 생성해준다. 설정을 완료하면 Api Token 값이 온다.

해당 값을 통해서 봇을 핸들링할수있다. BotFather의 간략한 명령어

  * /newbot - create a new bot
  * /token - generate authorization token
  * /revoke - revoke bot access token
  * /setname - change a bot's name
  * /setdescription - change bot description
  * /setabouttext - change bot about info
  * /setuserpic - change bot profile photo
  * /setinline - change inline settings
  * /setinlinefeedback - change inline feedback settings
  * /setcommands - change bot commands list
  * /setjoingroups - can your bot be added to groups?
  * /setprivacy - what messages does your bot see in groups?
  * /deletebot - delete a bot
  * /cancel - cancel the current operation

![](/assets/images/posts/490/2726BB46569DFDC4214244.PNG)

![](/assets/images/posts/490/256ABB45569DFE112501AE.PNG)

![](/assets/images/posts/490/245A053D569DFEAB1B8303.JPEG)

Bot Api 에 기재된 내용들을 참고해서, 요청하면 된다.

자 그럼 이제 cli를 통한 사용법에 대해 알아봅시다.

우선 서버에 Telegram을 설치합시다.

소스 설치

    git clone --recursive https://github.com/vysheng/tg.git

빌드 툴 설치

apt-get install libreadline-dev libconfig-dev libssl-dev lua5.2 liblua5.2-dev
libevent-dev libjansson-dev libpython-dev make 빌드 ./configure make

인증

    ./bin/telegram-cli -k tg-server.pubchange_user_group: can't find the user telegramd to switch toTelegram-cli version 1.3.3, Copyright (C) 2013-2015 Vitaly ValtmanTelegram-cli comes with ABSOLUTELY NO WARRANTY; for details type `show_license'.This is free software, and you are welcome to redistribute itunder certain conditions; type `show_license' for details.Telegram-cli uses libtgl version 2.0.3Telegram-cli includes software developed by the OpenSSL Projectfor use in the OpenSSL Toolkit. (http://www.openssl.org/)Telegram-cli uses libpython version 2.7.6I: config dir=[/root/.telegram-cli][/root/.telegram-cli] created[/root/.telegram-cli/downloads] createdphone number: 영준이code ('CALL' for phone code): 안알랴줌User 영준 우 online (was online [2016/01/19 05:11:18])

연결할 핸드폰 번호를 입력하고, 해당 번호로 온 인증번호를 입력합니다. 그럼 정상적으로 로그인합니다.

그럼런 간단하게 다른 사람에게 메세지를 보내보도록합시다.

준호에게 메세지를 보냈습니다.

    [05:20]  Jang Junho  msg Jang_Junho 테스트[05:20]  Jang Junho  msg Jang_Junho 테스트오호호오[05:20]  Jang Junho <<< 테스트오호호오

잘 되네요. 자신이 사용하는 사이드언어를 통해서 간단한 프로그램 만들어보세요.

위에서 말했듯이 텔레그램을 통해서 주기적인 서버상태 확인 과 명령어등을 통해서 핸들링할수있습니다. 다방면으로 아주 유용한 친구입니다.

아래 Telegram CLI 명령어들을 소개하고, 급하게 포스팅 마무리 짓 겠습니다. 바쁘다는 핑계로..ㅜㅜ 그럼 즐거운
플밍하십쇼.*(꾸벅)

![](/assets/images/posts/490/245EB935569E00E710F9B0.PNG)

  * accept_secret_chat <secret chat> Accepts secret chat. Only useful with -E option
  * add_contact <phone> <first name> <last name> Tries to add user to contact list
  * broadcast <user>+ <text> Sends text to several users at once
  * chat_add_user <chat> <user> [msgs-to-forward] Adds user to chat. Sends him last msgs-to-forward message from this chat. Default 100
  * chat_del_user <chat> <user> Deletes user from chat
  * chat_info <chat> Prints info about chat (id, members, admin, etc.)
  * chat_set_photo <chat> <filename> Sets chat photo. Photo will be cropped to square
  * chat_with_peer <peer> Interface option. All input will be treated as messages to this peer. Type /quit to end this mode
  * clear Clears all data and exits. For debug.
  * contact_list Prints contact list
  * contact_search username [limit] Searches contacts by username
  * create_group_chat <name> <user>+ Creates group chat with users
  * create_secret_chat <user> Starts creation of secret chat
  * del_contact <user> Deletes contact from contact list
  * delete_msg <msg-id> Deletes message
  * dialog_list List of last conversations
  * export_card Prints card that can be imported by another user with import_card method
  * fwd <peer> <msg-id> Forwards message to peer. Forward to secret chats is forbidden
  * fwd_media <peer> <msg-id> Forwards message media to peer. Forward to secret chats is forbidden. Result slightly differs from fwd
  * help Prints this help
  * history <peer> [limit] [offset] Prints messages with this peer (most recent message lower). Also marks messages as read
  * import_card <card> Gets user by card and prints it name. You can then send messages to him as usual
  * load_audio <msg-id> Downloads file to downloads dirs. Prints file name after download end
  * load_document <msg-id> Downloads file to downloads dirs. Prints file name after download end
  * load_document_thumb <msg-id> Downloads file to downloads dirs. Prints file name after download end
  * load_file <msg-id> Downloads file to downloads dirs. Prints file name after download end
  * load_file_thumb <msg-id> Downloads file to downloads dirs. Prints file name after download end
  * load_photo <msg-id> Downloads file to downloads dirs. Prints file name after download end
  * load_video <msg-id> Downloads file to downloads dirs. Prints file name after download end
  * load_video_thumb <msg-id> Downloads file to downloads dirs. Prints file name after download end
  * main_session Sends updates to this connection (or terminal). Useful only with listening socket
  * mark_read <peer> Marks messages with peer as read
  * msg <peer> <text> Sends text message to peer
  * quit Quits immediately
  * rename_chat <chat> <new name> Renames chat
  * rename_contact <user> <first name> <last name> Renames contact
  * restore_msg <msg-id> Restores message. Only available shortly (one hour?) after deletion
  * safe_quit Waits for all queries to end, then quits
  * search [peer] [limit] [from] [to] [offset] pattern Search for pattern in messages from date from to date to (unixtime) in messages with peer (if peer not present, in all messages) generate new key for active secret chat
  * send_audio <peer> <file> Sends audio to peer
  * send_contact <peer> <phone> <first-name> <last-name> Sends contact (not necessary telegram user)
  * send_document <peer> <file> Sends document to peer
  * send_file <peer> <file> Sends document to peer
  * send_location <peer> <latitude> <longitude> Sends geo location
  * send_photo <peer> <file> Sends photo to peer
  * send_text <peer> <file> Sends contents of text file as plain text message
  * send_typing <peer> Sends typing notification
  * send_typing <peer> Sends typing notification abort
  * send_video <peer> <file> Sends video to peer
  * set <param> <value> Sets value of param. Currently available: log_level, debug_verbosity, alarm, msg_num
  * set_password <hint> Sets password
  * set_profile_name <first-name> <last-name> Sets profile name.
  * set_profile_photo <filename> Sets profile photo. Photo will be cropped to square
  * set_ttl <secret chat> Sets secret chat ttl. Client itself ignores ttl
  * set_username <name> Sets username.
  * show_license Prints contents of GPL license
  * stats For debug purpose
  * status_online Sets status as online
  * status_offline Sets status as offline
  * user_info <user> Prints info about user (id, last online, phone)
  * view_audio <msg-id> Downloads file to downloads dirs. Then tries to open it with system default action
  * view_document <msg-id> Downloads file to downloads dirs. Then tries to open it with system default action
  * view_document_thumb <msg-id> Downloads file to downloads dirs. Then tries to open it with system default action
  * view_file <msg-id> Downloads file to downloads dirs. Then tries to open it with system default action
  * view_file_thumb <msg-id> Downloads file to downloads dirs. Then tries to open it with system default action
  * view_photo <msg-id> Downloads file to downloads dirs. Then tries to open it with system default action
  * view_video <msg-id> Downloads file to downloads dirs. Then tries to open it with system default action
  * view_video_thumb <msg-id> Downloads file to downloads dirs. Then tries to open it with system default action
  * visualize_key <secret chat> Prints visualization of encryption key (first 16 bytes sha1 of it in fact)


text:
describe Fastlane do
  describe Fastlane::FastFile do
    describe "Xcodebuild Integration" do
      before :each do
        Fastlane::Actions.lane_context.delete :IPA_OUTPUT_PATH
        Fastlane::Actions.lane_context.delete :XCODEBUILD_ARCHIVE
      end

      it "works with all parameters" do
        result = Fastlane::FastFile.new.parse("lane :test do
          xcodebuild(
            analyze: true,
            archive: true,
            build: true,
            clean: true,
            install: true,
            installsrc: true,
            test: true,
            arch: 'architecture',
            alltargets: true,
            archive_path: './build/MyApp.xcarchive',
            configuration: 'Debug',
            derived_data_path: '/derived/data/path',
            destination: 'name=iPhone 5s,OS=8.1',
            export_archive: true,
            export_format: 'ipa',
            export_installer_identity: true,
            export_path: './build/MyApp',
            export_profile: 'MyApp Distribution',
            export_signing_identity: 'Distribution: MyCompany, LLC',
            export_with_original_signing_identity: true,
            keychain: '/path/to/My.keychain',
            project: 'MyApp.xcodeproj',
            result_bundle_path: '/result/bundle/path',
            scheme: 'MyApp',
            sdk: 'iphonesimulator',
            skip_unavailable_actions: true,
            target: 'MyAppTarget',
            workspace: 'MyApp.xcworkspace',
            xcconfig: 'my.xcconfig',
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-alltargets " \
          + "-arch \"architecture\" " \
          + "-archivePath \"./build/MyApp.xcarchive\" " \
          + "-configuration \"Debug\" " \
          + "-destination \"name=iPhone 5s,OS=8.1\" " \
          + "-exportArchive " \
          + "-exportFormat \"ipa\" " \
          + "-exportInstallerIdentity " \
          + "-exportPath \"./build/MyApp\" " \
          + "-exportProvisioningProfile \"MyApp Distribution\" " \
          + "-exportSigningIdentity \"Distribution: MyCompany, LLC\" " \
          + "-exportWithOriginalSigningIdentity " \
          + "-project \"MyApp.xcodeproj\" " \
          + "-resultBundlePath \"/result/bundle/path\" " \
          + "-scheme \"MyApp\" " \
          + "-sdk \"iphonesimulator\" " \
          + "-skipUnavailableActions " \
          + "-target \"MyAppTarget\" " \
          + "-workspace \"MyApp.xcworkspace\" " \
          + "-xcconfig \"my.xcconfig\" " \
          + "OTHER_CODE_SIGN_FLAGS=\"--keychain /path/to/My.keychain\" " \
          + "analyze " \
          + "archive " \
          + "build " \
          + "clean " \
          + "install " \
          + "installsrc " \
          + "test " \
          + "| xcpretty --color --simple"
      )
    end

    it "works with build settings" do
      result = Fastlane::FastFile.new.parse("lane :test do
        xcodebuild(
          build_settings: {
            'CODE_SIGN_IDENTITY' => 'iPhone Developer: Josh',
            'JOBS' => 16,
            'PROVISIONING_PROFILE' => 'JoshIsCoolProfile'
          }
        )
      end").runner.execute(:test)

      expect(result).to include('CODE_SIGN_IDENTITY="iPhone Developer: Josh"')
      expect(result).to include('JOBS="16"')
      expect(result).to include('PROVISIONING_PROFILE="JoshIsCoolProfile"')
    end

    it "when archiving, should cache the archive path for a later export step" do
        Fastlane::FastFile.new.parse("lane :test do
          xcodebuild(
            archive: true,
            archive_path: './build/MyApp.xcarchive',
            scheme: 'MyApp',
            workspace: 'MyApp.xcworkspace'
          )
        end").runner.execute(:test)

        expect(Fastlane::Actions.lane_context[:XCODEBUILD_ARCHIVE]).to eq("./build/MyApp.xcarchive")
    end

    it "when exporting, should use the cached archive path from a previous archive step" do
        result = Fastlane::FastFile.new.parse("lane :test do
          xcodebuild(
            archive: true,
            archive_path: './build-dir/MyApp.xcarchive',
            scheme: 'MyApp',
            workspace: 'MyApp.xcworkspace'
          )

          xcodebuild(
            export_archive: true,
            export_path: './build-dir/MyApp'
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-archivePath \"./build-dir/MyApp.xcarchive\" " \
          + "-exportArchive " \
          + "-exportFormat \"ipa\" " \
          + "-exportPath \"./build-dir/MyApp\" " \
          + "| xcpretty --color --simple"
        )
    end

    it "when exporting, should cache the ipa path for a later deploy step" do
        Fastlane::FastFile.new.parse("lane :test do
          xcodebuild(
            archive_path: './build-dir/MyApp.xcarchive',
            export_archive: true,
            export_path: './build-dir/MyApp'
          )
        end").runner.execute(:test)

        expect(Fastlane::Actions.lane_context[:IPA_OUTPUT_PATH]).to eq("./build-dir/MyApp.ipa")
    end

    context "when using environment variables"
      before :each do
        ENV["XCODE_BUILD_PATH"] = "./build-dir/"
        ENV["XCODE_SCHEME"] = "MyApp"
        ENV["XCODE_WORKSPACE"] = "MyApp.xcworkspace"
      end

      after :each do
        ENV.delete("XCODE_BUILD_PATH")
        ENV.delete("XCODE_SCHEME")
        ENV.delete("XCODE_WORKSPACE")
      end

      it "can archive" do
        result = Fastlane::FastFile.new.parse("lane :test do
          xcodebuild(
            archive: true
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-archivePath \"./build-dir/MyApp.xcarchive\" " \
          + "-scheme \"MyApp\" " \
          + "-workspace \"MyApp.xcworkspace\" " \
          + "archive " \
          + "| xcpretty --color --simple"
        )
      end

      it "can export" do
        ENV.delete("XCODE_SCHEME")
        ENV.delete("XCODE_WORKSPACE")
        result = Fastlane::FastFile.new.parse("lane :test do
          xcodebuild(
            archive_path: './build-dir/MyApp.xcarchive',
            export_archive: true
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-archivePath \"./build-dir/MyApp.xcarchive\" " \
          + "-exportArchive " \
          + "-exportFormat \"ipa\" " \
          + "-exportPath \"./build-dir/MyApp\" " \
          + "| xcpretty --color --simple"
        )
      end
    end

    describe "xcarchive" do
      it "is equivalent to 'xcodebuild archive'" do
        result = Fastlane::FastFile.new.parse("lane :test do
          xcarchive(
            archive_path: './build-dir/MyApp.xcarchive',
            scheme: 'MyApp',
            workspace: 'MyApp.xcworkspace'
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-archivePath \"./build-dir/MyApp.xcarchive\" " \
          + "-scheme \"MyApp\" " \
          + "-workspace \"MyApp.xcworkspace\" " \
          + "archive " \
          + "| xcpretty --color --simple"
        )
      end
    end

    describe "xcbuild" do
      it "is equivalent to 'xcodebuild build'" do
        result = Fastlane::FastFile.new.parse("lane :test do
          xcbuild(
            scheme: 'MyApp',
            workspace: 'MyApp.xcworkspace'
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-scheme \"MyApp\" " \
          + "-workspace \"MyApp.xcworkspace\" " \
          + "build " \
          + "| xcpretty --color --simple"
        )
      end
    end

    describe "xcclean" do
      it "is equivalent to 'xcodebuild clean'" do
        result = Fastlane::FastFile.new.parse("lane :test do
          xcclean
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && xcodebuild clean | xcpretty --color --simple"
        )
      end
    end

    describe "xcexport" do
      it "is equivalent to 'xcodebuild -exportArchive'" do
        result = Fastlane::FastFile.new.parse("lane :test do
          xcexport(
            archive_path: './build-dir/MyApp.xcarchive',
            export_path: './build-dir/MyApp',
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-archivePath \"./build-dir/MyApp.xcarchive\" " \
          + "-exportArchive " \
          + "-exportFormat \"ipa\" " \
          + "-exportPath \"./build-dir/MyApp\" " \
          + "| xcpretty --color --simple"
        )
      end
    end

    describe "xctest" do
      it "is equivalent to 'xcodebuild test'" do
        result = Fastlane::FastFile.new.parse("lane :test do
          xctest(
            destination: 'name=iPhone 5s,OS=8.1',
            scheme: 'MyApp',
            workspace: 'MyApp.xcworkspace'
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-destination \"name=iPhone 5s,OS=8.1\" " \
          + "-scheme \"MyApp\" " \
          + "-workspace \"MyApp.xcworkspace\" " \
          + "test " \
          + "| xcpretty --color --test"
        )
      end
    end

    describe "test reporting" do
      it "should work with xcpretty report params" do
        result = Fastlane::FastFile.new.parse("lane :test do
          xctest(
            destination: 'name=iPhone 5s,OS=8.1',
            scheme: 'MyApp',
            workspace: 'MyApp.xcworkspace',
            report_formats: ['junit'],
            report_path: './build-dir/test-report'
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-destination \"name=iPhone 5s,OS=8.1\" " \
          + "-scheme \"MyApp\" " \
          + "-workspace \"MyApp.xcworkspace\" " \
          + "test " \
          + "| xcpretty --color " \
          + "--report junit " \
          + "--output \"./build-dir/test-report\" " \
          + "--test"
        )
      end

      it "should save reports to BUILD_PATH + \"/report\" by default" do
        ENV["XCODE_BUILD_PATH"] = "./build"

        result = Fastlane::FastFile.new.parse("lane :test do
          xctest(
            destination: 'name=iPhone 5s,OS=8.1',
            scheme: 'MyApp',
            workspace: 'MyApp.xcworkspace',
            report_formats: ['html'],
            report_screenshots: true
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-destination \"name=iPhone 5s,OS=8.1\" " \
          + "-scheme \"MyApp\" " \
          + "-workspace \"MyApp.xcworkspace\" " \
          + "test " \
          + "| xcpretty --color " \
          + "--report html " \
          + "--screenshots " \
          + "--output \"./build/report\" " \
          + "--test"
        )

        ENV.delete("XCODE_BUILD_PATH")
      end

      it "should support multiple output formats" do
        result = Fastlane::FastFile.new.parse("lane :test do
          xctest(
            destination: 'name=iPhone 5s,OS=8.1',
            scheme: 'MyApp',
            workspace: 'MyApp.xcworkspace',
            report_formats: [ 'html', 'junit', 'json-compilation-database' ]
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-destination \"name=iPhone 5s,OS=8.1\" " \
          + "-scheme \"MyApp\" " \
          + "-workspace \"MyApp.xcworkspace\" " \
          + "test " \
          + "| xcpretty --color " \
          + "--report html " \
          + "--report json-compilation-database " \
          + "--report junit " \
          + "--test"
        )
      end

      it "should support multiple reports " do
        result = Fastlane::FastFile.new.parse("lane :test do
          xctest(
            destination: 'name=iPhone 5s,OS=8.1',
            scheme: 'MyApp',
            workspace: 'MyApp.xcworkspace',
            reports: [{
              report: 'html',
              output: './build-dir/test-report.html',
              screenshots: 1
            },
            {
              report: 'junit',
              output: './build-dir/test-report.xml'
            }],
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-destination \"name=iPhone 5s,OS=8.1\" " \
          + "-scheme \"MyApp\" " \
          + "-workspace \"MyApp.xcworkspace\" " \
          + "test " \
          + "| xcpretty --color " \
          + "--report html " \
          + "--output \"./build-dir/test-report.html\" " \
          + "--screenshots " \
          + "--report junit " \
          + "--output \"./build-dir/test-report.xml\" " \
          + "--test"
        )
      end

      it "should support ommiting output when specifying multiple reports " do
        ENV["XCODE_BUILD_PATH"] = "./build"

        result = Fastlane::FastFile.new.parse("lane :test do
          xctest(
            destination: 'name=iPhone 5s,OS=8.1',
            scheme: 'MyApp',
            workspace: 'MyApp.xcworkspace',
            reports: [{
              report: 'html',
            },
            {
              report: 'junit',
            }],
          )
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-destination \"name=iPhone 5s,OS=8.1\" " \
          + "-scheme \"MyApp\" " \
          + "-workspace \"MyApp.xcworkspace\" " \
          + "test " \
          + "| xcpretty --color " \
          + "--report html " \
          + "--output \"./build/report/report.html\" " \
          + "--report junit " \
          + "--output \"./build/report/report.xml\" " \
          + "--test"
        )
      end
      it "should detect and use the workspace, when a workspace is present" do
        allow(Dir).to receive(:glob).with("*.xcworkspace").and_return([ "MyApp.xcworkspace" ])

        result = Fastlane::FastFile.new.parse("lane :test do
          xcbuild
        end").runner.execute(:test)

        expect(result).to eq(
          "set -o pipefail && " \
          + "xcodebuild " \
          + "-workspace \"MyApp.xcworkspace\" " \
          + "build " \
          + "| xcpretty --color " \
          + "--simple"
        )
      end
    end
  end
end

redpajama_set_name: RedPajamaGithub


text:
<?php
/**
 * Deals Class
 * Controller for all the deals realated activities
 *
 * @package     EMarketingPortal
 * @author      Thilina Solomons
 */
class Deals extends CI_Controller {

        public function __construct()
        {
                parent::__construct();
                session_start();

        }

        /**
        * Shows currently active deals for buyers
        *
        * @access   public
        * @return   void
        */
        public function all_deals(){
                $data['title'] = 'Deals';
                $this->load->model('deals_model');
                //get deals from the deals model
                $data['deals'] = $this->deals_model->get_all_deals();
                //loading views
                $this->load->view('templates/header', $data);
                $this->load->view('templates/search_box');
                $this->load->view('all_deals_view', $data);
                $this->load->view('templates/footer');
        }

        /**
        * Shows manage deals page for logged in seller
        *
        * @access   public
        * @return   void
        */
        public function manage_deals(){
                $data['title'] = 'Manage Deals';
                $this->load->model('deals_model');
                //getting the list of deals of logged in seller
                $data['deals'] = $this->deals_model->get_sellers_deals();

                //loading views
                $this->load->view('templates/header', $data);
                $this->load->view('templates/search_box');
                $this->load->view('manage_deals_view', $data);
                $this->load->view('templates/footer');
        }

        /**
        * Shows the select Item page for Creating a new deal
        *
        * @access   public
        * @return   void
        */
        public function select_item(){
                $data['title'] = 'Select Item';
                $this->load->model('deals_model');
                $data['items'] = $this->deals_model->get_sellers_items();

                //loading views
                $this->load->view('templates/header', $data);
                $this->load->view('templates/search_box');
                $this->load->view('create_deal_select_item_view', $data);
                $this->load->view('templates/footer');
        }

        /**
        * Shows the page for Creating a new deal for a Item passed as $_GET variable
        *
        * @access   public
        * @return   void
        */
        public function create_deal(){
                $data['title'] = 'Create Deal';
                $this->load->model('deals_model');

                //Getting the item info
                $item_id = $this->input->get('item');
                $this->load->model('item_model');
                $data['items'] = $this->item_model->item($item_id);

                //loading views
                $this->load->view('templates/header', $data);
                $this->load->view('templates/search_box');
                $this->load->view('create_deal_view', $data);
                $this->load->view('templates/footer');
        }

        /**
        * Submits the create deal info and redirects back to Manage deals page
        *
        * @access   public
        * @return   void
        */
        public function create_deal_submit(){
                $data['title'] = 'Create Deal';
                $this->load->model('deals_model');

                //Getting the deal info
                $item_id = $this->input->post('item');
                $end_date = $this->input->post('date') . ' ' . $this->input->post('time') . ':00';
                $off_perc = $this->input->post('percentage');

                $this->load->helper('url');
                //Creating the deal
                if($this->deals_model->create_deal($item_id, $end_date, $off_perc)){

					//Checking the wishlist items .
						$this->load->model('wishlist_model');
						$this->wishlist_model->check($item_id, $off_perc);

                        redirect('/Deals/manage_deals', 'refresh');
                }else{
                        redirect('/Deals/create_deal/?item=' . $item_id . '&error=TRUE', 'refresh');
                }

        }

        /**
        * Ends a deal when seller removes a deal on the manage deal page
        * Redirects back to Manage deals page when done
        *
        * @access   public
        * @return   void
        */
        public function end_deal(){
                $this->load->model('deals_model');

                //Getting the deal info
                $deal_id = $this->input->get('deal');
                $this->deals_model->end_deal($deal_id);
                //shows manage deals page
                $this->load->helper('url');
                redirect('/Deals/manage_deals', 'refresh');
        }
}


text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;

namespace Microsoft.Common.Core.Shell {

    /// <summary>
    /// Specifies which buttons to show in a message box.
    /// Also used as a return value to tell which button
    /// was pressed.
    /// </summary>
    [Flags]
    public enum MessageButtons {
        OK = 0,
        Cancel = 0x01,
        Yes = 0x02,
        No = 0x04,
        OKCancel = OK | Cancel,
        YesNo = Yes | No,
        YesNoCancel = YesNo | Cancel,
    }
}


text:
import {Component, ViewChild} from "@angular/core";
import {JigsawMobileInput} from "jigsaw/mobile_public_api";

@Component({
    templateUrl: './demo.component.html'
})
export class InputBasicDemoComponent {
    inputValue: any;

    valueChanged(message: string) {
        console.log(`input value is: ${message}`);
    }

    @ViewChild('myInput') myInput: JigsawMobileInput;

    click() {
        alert('你输入的值是 ' + this.myInput.value)
    }

    // ====================================================================
    // ignore the following lines, they are not important to this demo
    // ====================================================================
    summary: string = '';
    description: string = '';
}


text:
<resources>
    <string name="app_name">Журнал</string>
    <string name="title_activity_news">Новости</string>
    <string name="download">Загрузка</string>
    <string name="facebook">Фейсбук</string>
    <string name="twitter">Твиттер</string>
    <string name="prefCatNotifications">Оповещения</string>
    <string name="prefNotificationsTitle">Включить оповещения</string>
    <string name="actionSettings">Параметры</string>
    <string name="drawerOpen">Drawer Open</string>
    <string name="drawerClose">Drawer Close</string>
    <string name="explore">Исследовать</string>
    <string name="actionEditCategories">Редактирование категорий</string>
    <string name="actionAddCategory">Добавить категорию</string>
    <string name="addCategory">Добавить новую категорию</string>
    <string name="addCategoryDialogMessage">Введите название для новой категории</string>
    <string name="addNewsFeed">Добавить новую ленту новостей</string>
    <string name="addNewsFeedLabelEditText">Название</string>
    <string name="addNewsFeedLinkEditText">Ссылка</string>
    <string name="add">Добавить</string>

    <string name="facebook_app_id">185863238451126</string>
    <string name="fb_share_photo">Фото</string>
    <string name="fb_share_video">Видео</string>
    <string name="fb_share_link">Ссылка</string>
    <string name="fb_user_feed">Новости</string>
    <string name="fb_user_likes_page">Лайки</string>
    <string name="fb_user_info">О пользователе</string>
    <string name="fb_page_feed">Новости</string>
    <string name="fb_page_info">О странице</string>

    <!-- TODO: Remove or change this placeholder text -->
    <string name="hello_blank_fragment">Hello blank fragment</string>
</resources>


text:
package cn.edu.xmu.dm.d3c.core;

import java.util.ArrayList;
import java.util.List;

import weka.classifiers.Classifier;

public class Parameterz {

	public List<List<Integer>> classifyRightOrWrong;
	public List<List<Integer>> classifyErrorNo;
	public List<Double> correctRateArray;
	public List<List<double[]>> classifyDistributeForInstances;
	public List<Integer> qqs;

	// 重新保存分类器信息
	public Classifier[] available_cfsArray;
	public List<List<Integer>> available_classifyRightOrWrong;
	public List<List<Integer>> available_classifyErrorNo;
	public List<Double> available_correctRateArray;
	public List<List<double[]>> available_classifyDistributeForInstances;
	public List<Integer> temp_qc_1;

	public Parameterz(int cfNum) {
		classifyRightOrWrong = new ArrayList<List<Integer>>();	// 用于记录每种分类器单独训练时分类情况,1表示分类正确,0表示分类错误
		classifyErrorNo = new ArrayList<List<Integer>>();		// 用于得到每种分类器单独训练时候错分实例的编号
		correctRateArray = new ArrayList<Double>();					// 用来存放各种算法的正确率
		classifyDistributeForInstances=new ArrayList<List<double[]>>();// 用来存放概率分布得到的数据
		qqs=new ArrayList<Integer>();

		available_cfsArray=new  Classifier[cfNum];
		available_classifyRightOrWrong=new ArrayList<List<Integer>>();
		available_classifyErrorNo = new ArrayList<List<Integer>>();
		available_correctRateArray = new ArrayList<Double>();
		available_classifyDistributeForInstances=new ArrayList<List<double[]>>();
		temp_qc_1=new ArrayList<Integer>();
	}
}


text:
package com.mykaruga.models.wavefront.loader;

public class TextureCoordinate {

	private float u;
	private float v;
	private float w;

	public float getU() {
		return u;
	}

	public void setU(float u) {
		this.u = u;
	}

	public float getV() {
		return v;
	}

	public void setV(float v) {
		this.v = v;
	}

	public float getW() {
		return w;
	}

	public void setW(float w) {
		this.w = w;
	}

}


text:
#region licence

#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Diagnostics;
using EV3MessengerLib.Protocol;
using System.Collections.Concurrent;

namespace EV3MessengerLib.Communication
{
    internal class Communicator
    {
        private PayloadParser payloadParser;
        private ConcurrentQueue<Payload> readPayloadsQueue;
        private SerialPort serialPort;
        private Object connectLock;

        /// <summary>
        /// The connection state. True if connected, false otherwise.
        /// </summary>
        public bool IsConnected
        {
            get { return serialPort.IsOpen; }
        }

        /// <summary>
        /// Gets the serial port name if connected. Returns the port name or null of not connected.
        /// </summary>
        public string Port
        {
            get
            {
                try
                {
                    if (serialPort.IsOpen)
                    {
                        return serialPort.PortName;
                    }
                }
                catch (Exception e) // Very dirty :)
                {
                    Debug.WriteLine("Catched an exception while asking for the port name: " + e.Message);
                    Debug.WriteLine(e.StackTrace);
                }
                return null;
            }
        }

        /// <summary>
        /// Creates an object for communicating (serial over Bluetooth) with the EV3.
        /// </summary>
        public Communicator()
        {
            payloadParser = new PayloadParser();
            readPayloadsQueue = new ConcurrentQueue<Payload>();

            serialPort = new SerialPort();
            serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

            connectLock = new Object();
        }

        /// <summary>
        /// Connects to the given serial port.
        /// If the conncection succeeded, then reading of messages will start.
        /// </summary>
        /// <param name="port">The port to connect to. E.g. "COM1", "COM8", etc.</param>
        /// <returns>True if the connection was made, false otherwise.</returns>
        public bool Connect(string port)
        {
            if (port == null)
            {
                throw new ArgumentNullException("port");
            }

            lock (connectLock)
            {
                if (!serialPort.IsOpen
                    && IsValidPort(port))
                {
                    payloadParser.ClearData();
                    ClearReadPayloadsQueue();
                    try
                    {
                        serialPort.PortName = port;
                        serialPort.Open();
                        serialPort.DiscardInBuffer();
                        serialPort.DiscardOutBuffer();
                        return true;
                    }
                    catch (Exception e) // Very dirty :)
                    {
                        Debug.WriteLine("Catched an exception while connecting: " + e.Message);
                        Debug.WriteLine(e.StackTrace);
                    }
                }
                return false;
            }
        }

        /// <summary>
        /// Send a raw message.
        /// </summary>
        /// <param name="rawMessage">The message to send (for valid format, see FieldInfo class)</param>
        /// <returns>True if send, false otherwise.</returns>
        public bool Send(byte[] rawMessage)
        {
            if (rawMessage == null)
            {
                throw new ArgumentNullException("rawMessage");
            }

            if (serialPort.IsOpen)
            {
                if (rawMessage.Length != 0)
                {
                    try
                    {
                        serialPort.Write(rawMessage, 0, rawMessage.Length);
                        Debug.WriteLine("Message was send to the serial port.");
                        return true;
                    }
                    catch (Exception e) // Very dirty :)
                    {
                        Debug.WriteLine("Catched an exception while sending a raw message: " + e.Message);
                        Debug.WriteLine(e.StackTrace);
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// Close the current connection and stop the reading of messages.
        /// </summary>
        public bool Disconnect()
        {
            lock (connectLock)
            {
                if (serialPort.IsOpen)
                {
                    try
                    {
                        serialPort.DiscardInBuffer();
                        serialPort.DiscardOutBuffer();
                        serialPort.Close();

                        payloadParser.ClearData();
                        ClearReadPayloadsQueue();
                        return true;
                    }
                    catch (Exception e) // Very dirty :)
                    {
                        Debug.WriteLine("Catched an exception while disconnecting: " + e.Message);
                        Debug.WriteLine(e.StackTrace);
                    }
                }
                return false;
            }
        }

        private bool IsValidPort(string port)
        {
            if (port != null)
            {
                string[] portNames = SerialPort.GetPortNames();
                foreach (string portName in portNames)
                {
                    if (portName.ToUpper() == port.ToUpper())
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// Get the next payload from the queue of read payloads.
        /// </summary>
        /// <returns>the next payload or null if no payload was read yet.</returns>
        public Payload GetNextReadPayload()
        {
            Payload payload;
            if (readPayloadsQueue.TryDequeue(out payload))
            {
                return payload;
            }
            return null;
        }

        private void ClearReadPayloadsQueue()
        {
            while (readPayloadsQueue.Count > 0)
            {
                Payload payload;
                readPayloadsQueue.TryDequeue(out payload);
            }
        }

        private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort serialPort = (SerialPort)sender;
            if (serialPort.IsOpen)
            {
                try
                {
                    int nrOfBytesToRead = serialPort.BytesToRead;

                    if (nrOfBytesToRead > 0)
                    {
                        byte[] readBytes = new byte[nrOfBytesToRead];
                        int nrOfBytesRead = serialPort.Read(readBytes, 0, readBytes.Length);
                        Debug.Assert(nrOfBytesToRead == nrOfBytesRead);

                        payloadParser.AppendData(readBytes);
                        Payload payload = payloadParser.FindAndRemoveNextPayload();
                        while (payload != null)
                        {
                            readPayloadsQueue.Enqueue(payload);
                            payload = payloadParser.FindAndRemoveNextPayload();
                        }
                    }
                }
                catch (Exception exception) // Very dirty :)
                {
                    Debug.WriteLine("Catched an exception while reading bytes from the serial port: " + exception.Message);
                    Debug.WriteLine(exception.StackTrace);
                }
            }
        }
    }
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>com.yahoo.yui.charts - YUI AS Component Documentation</title>
<base target="classFrame">
<link rel="stylesheet" href="../../../../style.css" type="text/css" media="screen">
<link rel="stylesheet" href="../../../../print.css" type="text/css" media="print">

Package com.yahoo.yui.charts

Classes

AxisSerializer

BackgroundAndBorder

BackgroundImageMode

ChartSerializer

SeriesSerializer

TextFormatSerializer


text:
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';

@Injectable()
export class PostsService {

  constructor(private _http: Http) {

  }

  getPosts() {
  	return this._http.get('/api/posts')
  		.map((response: Response) => response.json())
  		.do(data => console.log('All' + JSON.stringify(data)));
  }

  createPost (posts) {
  	let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });

  	return this._http.post('/api/posts', JSON.stringify(posts), options)
  		.map((response: Response) => response.json())
  		.do(data => console.log('All' + JSON.stringify(data)));
  }

  deletePost (id) {
    return this._http.delete('/api/posts/' + id)
      .map((response: Response) => response.json())
      .do(data => console.log('All' + JSON.stringify(data)));
  }

}


text:
namespace pdalboost {
namespace intrusive {

template<class It>
class reverse_iterator
{
   public:
   typedef typename pdalboost::intrusive::iterator_traits<It>::pointer             pointer;
   typedef typename pdalboost::intrusive::iterator_traits<It>::reference           reference;
   typedef typename pdalboost::intrusive::iterator_traits<It>::difference_type     difference_type;
   typedef typename pdalboost::intrusive::iterator_traits<It>::iterator_category   iterator_category;
   typedef typename pdalboost::intrusive::iterator_traits<It>::value_type          value_type;

   typedef It iterator_type;

   reverse_iterator()
      : m_current()  //Value initialization to achieve "null iterators" (N3644)
      {}

   explicit reverse_iterator(It r)
      : m_current(r)
   {}

   template<class OtherIt>
   reverse_iterator( const reverse_iterator<OtherIt>& r
                   , typename pdalboost::intrusive::detail::enable_if_convertible<OtherIt, It>::type* =0
                   )
      : m_current(r.base())
   {}

   template<class OtherIt>
   typename pdalboost::intrusive::detail::enable_if_convertible<OtherIt, It, reverse_iterator &>::type
         operator=( const reverse_iterator<OtherIt>& r)
   {  m_current = r.base();   return *this;  }

   It base() const
   {  return m_current;  }

   reference operator*() const
   {  It temp(m_current);   --temp; return *temp; }

   pointer operator->() const
   {  It temp(m_current);   --temp; return iterator_arrow_result(temp); }

   reference operator[](difference_type off) const
   {  return this->m_current[-off - 1];  }

   reverse_iterator& operator++()
   {  --m_current;   return *this;   }

   reverse_iterator operator++(int)
   {
      reverse_iterator temp = *this;
      --m_current;
      return temp;
   }

   reverse_iterator& operator--()
   {
      ++m_current;
      return *this;
   }

   reverse_iterator operator--(int)
   {
      reverse_iterator temp(*this);
      ++m_current;
      return temp;
   }

   friend bool operator==(const reverse_iterator& l, const reverse_iterator& r)
   {  return l.m_current == r.m_current;  }

   friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r)
   {  return l.m_current != r.m_current;  }

   friend bool operator<(const reverse_iterator& l, const reverse_iterator& r)
   {  return l.m_current > r.m_current;  }

   friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r)
   {  return l.m_current >= r.m_current;  }

   friend bool operator>(const reverse_iterator& l, const reverse_iterator& r)
   {  return l.m_current < r.m_current;  }

   friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r)
   {  return l.m_current <= r.m_current;  }

   reverse_iterator& operator+=(difference_type off)
   {  m_current -= off; return *this;  }

   friend reverse_iterator operator+(reverse_iterator l, difference_type off)
   {  l.m_current -= off;  return l;  }

   friend reverse_iterator operator+(difference_type off, reverse_iterator r)
   {  return (r += off);   }

   reverse_iterator& operator-=(difference_type off)
   {  m_current += off; return *this;  }

   friend reverse_iterator operator-(reverse_iterator l, difference_type off)
   {  l.m_current += off;  return l;  }

   friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r)
   {  return r.m_current - l.m_current;  }

   private:
   It m_current;   // the wrapped iterator
};

} //namespace intrusive {
} //namespace pdalboost {

#include <boost/intrusive/detail/config_end.hpp>

#endif //BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP


text:
package option

import (
	"context"
	"flag"
	"fmt"
	"strconv"

	"github.com/vmware/govmomi/govc/cli"
	"github.com/vmware/govmomi/govc/flags"
	"github.com/vmware/govmomi/object"
	"github.com/vmware/govmomi/vim25/soap"
	"github.com/vmware/govmomi/vim25/types"
)

type Set struct {
	*flags.ClientFlag
}

func init() {
	cli.Register("option.set", &Set{})
}

func (cmd *Set) Register(ctx context.Context, f *flag.FlagSet) {
	cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
	cmd.ClientFlag.Register(ctx, f)
}

func (cmd *Set) Process(ctx context.Context) error {
	if err := cmd.ClientFlag.Process(ctx); err != nil {
		return err
	}
	return nil
}

func (cmd *Set) Usage() string {
	return "NAME VALUE"
}

var SetDescription = `Set option NAME to VALUE.`

func (cmd *Set) Description() string {
	return SetDescription + `

Examples:
  govc option.set log.level info
  govc option.set logger.Vsan verbose`
}

func isInvalidName(err error) bool {
	if soap.IsSoapFault(err) {
		soapFault := soap.ToSoapFault(err)
		if _, ok := soapFault.VimFault().(types.InvalidName); ok {
			return ok
		}
	}

	return false
}

func (cmd *Set) Update(ctx context.Context, f *flag.FlagSet, m *object.OptionManager) error {
	if f.NArg() != 2 {
		return flag.ErrHelp
	}

	name := f.Arg(0)
	val := f.Arg(1)

	opts, err := m.Query(ctx, name)
	if err != nil {
		if isInvalidName(err) {
			// If the option doesn't exist, creating one can only have a string Value.
			// The Key prefix is limited in this case too, it seems to the config.* namespace.
			return m.Update(ctx, []types.BaseOptionValue{&types.OptionValue{
				Key:   name,
				Value: val,
			}})
		}
		return err
	}

	if len(opts) != 1 {
		return flag.ErrHelp
	}

	var set types.AnyType

	switch x := opts[0].GetOptionValue().Value.(type) {
	case string:
		set = val
	case bool:
		set, err = strconv.ParseBool(val)
		if err != nil {
			return err
		}
	case int32:
		s, err := strconv.ParseInt(val, 10, 32)
		if err != nil {
			return err
		}
		set = int32(s)
	case int64:
		set, err = strconv.ParseInt(val, 10, 64)
		if err != nil {
			return err
		}
	default:
		return fmt.Errorf("type %T conversion not supported", x)
	}

	opts[0].GetOptionValue().Value = set

	return m.Update(ctx, opts)
}

func (cmd *Set) Run(ctx context.Context, f *flag.FlagSet) error {
	c, err := cmd.Client()
	if err != nil {
		return err
	}

	m := object.NewOptionManager(c, *c.ServiceContent.Setting)

	return cmd.Update(ctx, f, m)
}


text:
A minimalistic, cross-platform BitTorrent client written in Haskell.

Development for this project is currently happening in other components - chunks of functionality modularized into seperate libraries to maximize code re-use. See the following repositories:

* [nickspinale/bigword](http://github.com/nickspinale/bigword): Library for constructing and inspecting bitvectors with statically known size as heterogeneous Church-encoded vectors.
* [nickspinale/becode](http://github.com/nickspinale/bencode): Efficient and flexible parsers and builders for Bencode.
* [nickspinale/aether](http://github.com/nickspinale/aether): Haskell implementation of the Mainline Distributed Hashtable.

No decisions have been made about the frontend yet.
It will most likely be flexible, like [Yi](https://github.com/yi-editor/yi)'s.

For more information, visit [nickspinale.com/projects.html](http://nickspinale.com/projects.html).


text:
Sometimes you need to abort or otherwise modify a loop (both `while` or `for` loops). You may want your program to exit it completely or skip part of it before continuing with the next iterations. You can do these actions with [break](./keywords/break.md) and [continue](./keywords/continue.md) python's keywords.

See [this blog post][exiting-loop-ref] for more details.

[exiting-loop-ref]: https://www.tutorialspoint.com/python/python_loop_control.htm


text:
package VMOMI::VirtualDevice;
use parent 'VMOMI::DynamicData';

use strict;
use warnings;

our @class_ancestors = (
    'DynamicData',
);

our @class_members = (
    ['key', undef, 0, ],
    ['deviceInfo', 'Description', 0, 1],
    ['backing', 'VirtualDeviceBackingInfo', 0, 1],
    ['connectable', 'VirtualDeviceConnectInfo', 0, 1],
    ['slotInfo', 'VirtualDeviceBusSlotInfo', 0, 1],
    ['controllerKey', undef, 0, 1],
    ['unitNumber', undef, 0, 1],
);

sub get_class_ancestors {
    return @class_ancestors;
}

sub get_class_members {
    my $class = shift;
    my @super_members = $class->SUPER::get_class_members();
    return (@super_members, @class_members);
}

1;


text:
The developer guide is for anyone wanting to either write code which directly accesses the
qingyuan API, or to contribute directly to the qingyuan project.
It assumes some familiarity with concepts in the [User Guide](user-guide.md) and the [Cluster Admin
Guide](cluster-admin-guide.md).

## Developing against the QingYuan API

* API objects are explained at [http://qingyuan/third_party/swagger-ui/](http://qingyuan/third_party/swagger-ui/).

* **Annotations** ([annotations.md](annotations.md)): are for attaching arbitrary non-identifying metadata to objects.
  Programs that automate QingYuan objects may use annotations to store small amounts of their state.

* **API Conventions** ([api-conventions.md](api-conventions.md)):
  Defining the verbs and resources used in the QingYuan API.

* **API Client Libraries** ([client-libraries.md](client-libraries.md)):
  A list of existing client libraries, both supported and user-contributed.

## Writing Plugins

* **Authentication Plugins** ([authentication.md](authentication.md)):
  The current and planned states of authentication tokens.

* **Authorization Plugins** ([authorization.md](authorization.md)):
  Authorization applies to all HTTP requests on the main apiserver port.
  This doc explains the available authorization implementations.

* **Admission Control Plugins** ([admission_control](design/admission_control.md))

## Contributing to the QingYuan Project

See this [README](../docs/devel/README.md).

[![Analytics](https://qingyuan-site.appspot.com/UA-36037335-10/GitHub/docs/developer-guide.md?pixel)]()

[![Analytics](https://qingyuan-site.appspot.com/UA-36037335-10/GitHub/release-0.19.0/docs/developer-guide.md?pixel)]()


text:
SELECT
    specimens.subject_id as person_id,
    0 as specimen_concept_id,
    0 as specimen_type_concept_id,
    specimens.charttime as specimen_date,
    pg_catalog.time(specimens.charttime) as specimen_time,
    NULL as quantity,
    NULL as unit_concept_id,
    NULL as anatomic_site_concept_id,
    NULL as disease_status_concept_id,
    specimens.loinc_code as specimen_source_id,
    specimens.fluid as specimen_source_value,
    specimens.valueuom as unit_source_value,
    NULL as anatomic_site_source_value,
    NULL as disease_status_source_value
FROM
(
    SELECT
        *
    FROM
        mimic2v26.d_labitems as i,
        mimic2v26.labevents as e
    WHERE
        i.itemid =  e.itemid
 ) as specimens;


text:
DADA
====

I've tested building on various i386 and x86_64 Java/Linux
platforms. You will need a recent JDK and Maven (and probably
JAVA_HOME and MAVEN_HOME set).

For a demo of DADA please follow the instructions below. The demo
domain is whale sightings (I am fascinated by whales), however DADA is
generic enough to slice, dice and aggregate pretty much anything in
realtime. At the bank at which I currently work, it is being used by
Treasury to project 6 month cash trade settlement ladders and
highlight late amendments.

## Build DADA

git clone https://github.com/JulesGosnell/dada.git
cd dada
mvn clean install

## In one shell: Start DADA Whales Demo Server

cd dada/dada-demo
../bin/clj
(load-file "src/main/clojure/org/dada/demo/whales.clj")

## In another shell: Start DADA Client GUI

cd dada/dada-swt
../bin/clj
(System/exit 0)
cd ..
./bin/client

You should now be looking at DADA's MetaModel - it's Model of Models.

![Alt text](https://raw.github.com/JulesGosnell/dada/master/images/MetaModel.gif)

Click on the Whales Model.

![Alt text](https://raw.github.com/JulesGosnell/dada/master/images/Whales.gif)

 - A View of the Whales Model should open (you can open as many as you like)
 - This Model contains a live feed of whale sightings
 - A whale's attributes (except type) may vary from sighting to sighting

Click on the Oceans Model.

![Alt text](https://raw.github.com/JulesGosnell/dada/master/images/Oceans.gif)

 - A View of the Oceans Model should open (you can open as many as you like)
 - This Model contains a live feed of Ocean samplings
 - An Ocean's attributes may vary from sample to sample

Click on the WhalesAndOceans Model.

![Alt text](https://raw.github.com/JulesGosnell/dada/master/images/WhalesAndOceans.gif)

 - The WhalesAndOceans Model is derived from the Whales and Oceans Models by a query
 - This query demonstrates DADA's ability to join live streams/Models in real time
 - Each Whale is shown joined to its current Ocean (which may change over time)
 - Whale and Ocean attribute changes are reflected in realtime in the WhalesAndOceans Model

## In DADA Whales Demo Server shell/repl:

;; select namespace
(ns org.dada.demo.whales)
;; run query
(? (dunion)(dsum :weight)(dsplit :ocean)(dfrom "Whales"))

 - You should see a number of new Models leap into existence in the MetaModel
 - These Models are derived from the inital Whales and Oceans models via the query above
 - Intermediate Models are maintained so that they may also be viewed

![Alt text](https://raw.github.com/JulesGosnell/dada/master/images/MetaModel2.gif)

Click on the Whales:ocean.sum(:weight).union() Model.

![Alt text](https://raw.github.com/JulesGosnell/dada/master/images/WhaleWeightSummedByOcean.gif)

 - This Model maintains the ultimate result of the query that you have just entered
 - The Whales have been grouped by Ocean and the weight of Whales in each of these groups summed up.
 - As the weight and ocean attributes of the Whales change over time, so does this Model

Click on the Whales.split(:ocean=arctic) Model.

![Alt text](https://raw.github.com/JulesGosnell/dada/master/images/ArcticWhales.gif)

 - This is an intermediate Model contributing to the ultimate Model above.
 - It maintains the real time set of all Whales currently in the Arctic.

Click on the Whales.split(:ocean=arctic).sum(:weight) Model.

![Alt text](https://raw.github.com/JulesGosnell/dada/master/images/ActicWhalesTotalWeight.gif)

 - This is a intermediate Model drawing upon another intermediate Model and contributing to the ultimate Model above.
 - It represents the real time sum of the weight of all Whales currently in the Arctic.

DADA is a proof of concept, allowing me to learn about Event Stream
Processing in Clojure from the inside, not (yet) production software.

Clojure is an ideal platform on which to implement ESP - A functional
approach, sequence comprehension, simple concurrency, persistant
containers and immutable record types.

The only serious change that I have had to make to Clojure is enabling
the recording of dynamically created classes on the server and their
on-demand loading into a client. This allows me to run queries
server-side which create new functions and types and then to have
these pulled into the running client when needed to view the resultant
Models.


text:
package asw.efood.samplerestaurantclient.domain;

import org.springframework.stereotype.Component;
import org.springframework.boot.CommandLineRunner;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import java.util.*;
import java.util.logging.*;

@Component
public class RestaurantAsyncClientRunner implements CommandLineRunner {

	private final Logger logger = Logger.getLogger(this.getClass().toString());

	@Autowired
	private RestaurantClientAsyncPort restaurantClientAsyncAdapter;

	public void run(String[] args) throws InterruptedException, ExecutionException {
		logger.info("*** Cerco il ristorante con id=1L ***");
		CompletableFuture<Restaurant> futureRestaurant = restaurantClientAsyncAdapter.getRestaurantAsync(1L);
		// logger.info("*** Cerco il ristorante con id=1L *** -> done");
		logger.info(futureRestaurant.get().toString());

		logger.info("*** Creo un nuovo ristorante Alfa ***");
		CompletableFuture<Long> futureRestaurantId = restaurantClientAsyncAdapter.createRestaurantAsync("Alfa", "Roma");
		// logger.info("*** Creo un nuovo ristorante Alfa *** -> done");
		Long newRestaurantId = futureRestaurantId.get();
		logger.info(newRestaurantId.toString());
		logger.info("*** Cerco il ristorante appena creato ***");
		futureRestaurant = restaurantClientAsyncAdapter.getRestaurantAsync(newRestaurantId);
		// logger.info("*** Cerco il ristorante appena creato *** -> done");
		logger.info(futureRestaurant.get().toString());

		logger.info("*** Cerco tutti i ristoranti ***");
		CompletableFuture<List<Restaurant>> futureRestaurants = restaurantClientAsyncAdapter.getAllRestaurantsAsync();
		// logger.info("*** Cerco tutti i ristoranti *** -> done");
		logger.info(futureRestaurants.get().toString());
	}
}


text:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SharpCompress.Common;

namespace SharpCompress.Test
{
    [TestClass]
    public class ZipWriterTests : WriterTests
    {
        public ZipWriterTests()
            : base(ArchiveType.Zip)
        {
        }

        [TestMethod]
        public void Zip_Deflate_Write()
        {
            Write(CompressionType.Deflate, "Zip.deflate.noEmptyDirs.zip", "Zip.deflate.noEmptyDirs.zip");
        }

        [TestMethod]
        public void Zip_BZip2_Write()
        {
            Write(CompressionType.BZip2, "Zip.bzip2.noEmptyDirs.zip", "Zip.bzip2.noEmptyDirs.zip");
        }

        [TestMethod]
        public void Zip_None_Write()
        {
            Write(CompressionType.None, "Zip.none.noEmptyDirs.zip", "Zip.none.noEmptyDirs.zip");
        }

        [TestMethod]
        public void Zip_LZMA_Write()
        {
            Write(CompressionType.LZMA, "Zip.lzma.noEmptyDirs.zip", "Zip.lzma.noEmptyDirs.zip");
        }

        [TestMethod]
        public void Zip_PPMd_Write()
        {
            Write(CompressionType.PPMd, "Zip.ppmd.noEmptyDirs.zip", "Zip.ppmd.noEmptyDirs.zip");
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidFormatException))]
        public void Zip_Rar_Write()
        {
            Write(CompressionType.Rar, "Zip.ppmd.noEmptyDirs.zip", "Zip.ppmd.noEmptyDirs.zip");
        }
    }
}


text:
package jenkins.security.apitoken;

import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.Beta;

/**
 * Contains information about the token and the secret value.
 * It should not be stored as is, but just displayed once to the user and then forget about it.
 * @since This was added in 2.260 but marked NoExternalUse, opened as Beta in 2.265
 */
@Restricted(Beta.class)
public class TokenUuidAndPlainValue {
    /**
     * The token identifier to allow manipulation of the token
     */
    public final String tokenUuid;

    /**
     * Confidential information, must not be stored.<p>
     * It's meant to be send only one to the user and then only store the hash of this value.
     */
    public final String plainValue;

    public TokenUuidAndPlainValue(String tokenUuid, String plainValue) {
        this.tokenUuid = tokenUuid;
        this.plainValue = plainValue;
    }
}


text:
layout: page
title: "Nancy Smith"
comments: true
description: "blanks"
keywords: "Nancy Smith,CU,Boulder"
---
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://dl.dropboxusercontent.com/s/pc42nxpaw1ea4o9/highcharts.js?dl=0"></script>
<!-- <script src="../assets/js/highcharts.js"></script> -->
<style type="text/css">@font-face {
	font-family: "Bebas Neue";
	src: url(https://www.filehosting.org/file/details/544349/BebasNeue Regular.otf) format("opentype");
	}
	h1.Bebas {
		font-family: "Bebas Neue", Verdana, Tahoma;
	}
</style>
</head>

#### TEACHING INFORMATION

**College**: College of Arts and Sciences

**Classes taught**: DNCE 1901

#### DNCE 1901: Technique Practicum

**Terms taught**: Spring 2014

**Instructor rating**: 4.47

**Standard deviation in instructor rating**: 0.0

**Average grade** (4.0 scale): 3.44

**Standard deviation in grades** (4.0 scale): 0.0

**Average workload** (raw): 1.82

**Standard deviation in workload** (raw): 0.0


text:
package pl.pg.eti.kio.skroom.install;

import java.io.IOException;
import java.sql.SQLException;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import pl.pg.eti.kio.skroom.install.frame.WelcomeFrame;

public class Installer {
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				JFrame frame = new WelcomeFrame();
				frame.setVisible(true);
			}
		});
	}
}


text:
package org.bordeauxjug.mapstruct.immutable;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

/**
 * @author Christophe Labouisse on 10/04/2015.
 */
@Mapper
public abstract class CarMapper {

    public CarDto carToCarDto(Car car) {
        return carToCarDtoBuilder(car).createCarDto();
    }

    @Mappings({
            @Mapping(source = "make", target = "manufacturer"),
            @Mapping(source = "numberOfSeats", target = "seatCount")
    })
    protected abstract CarDtoBuilder carToCarDtoBuilder(Car car);
}


text:
package com.forgedui.editor.edit;

import com.forgedui.model.titanium.CoverFlowView;

public class CoverFlowEditPart extends TitaniumContainerEditPart<CoverFlowView> {

}


text:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Abstractions;

namespace PicklesDoc.Pickles.DocumentationBuilders.Html
{
    public class ResourceWriter
    {
        private readonly IFileSystem fileSystem;

        private readonly string namespaceOfResources;

        public ResourceWriter(IFileSystem fileSystem, string namespaceOfResources)
        {
            this.fileSystem = fileSystem;
            this.namespaceOfResources = namespaceOfResources;
        }

        protected IFileSystem FileSystem
        {
            get { return this.fileSystem; }
        }

        private static void CopyStream(Stream input, Stream output)
        {
            byte[] buffer = new byte[32768];
            while (true)
            {
                int read = input.Read(buffer, 0, buffer.Length);
                if (read <= 0)
                {
                    return;
                }

                output.Write(buffer, 0, read);
            }
        }

        protected void WriteStyleSheet(string folder, string filename)
        {
            string path = this.fileSystem.Path.Combine(folder, filename);

            using (var reader = this.GetResourceStreamReader(this.namespaceOfResources + "css." + filename))
            {
                this.fileSystem.File.WriteAllText(path, reader.ReadToEnd());
            }
        }

        protected void WriteTextFile(string folder, string filename)
        {
            this.WriteTextFile(folder, filename, null, null);
        }

        protected void WriteTextFile(string folder, string filename, string toBeReplaced, string replacement)
        {
            string path = this.fileSystem.Path.Combine(folder, filename);

            using (var reader = this.GetResourceStreamReader(this.namespaceOfResources + filename))
            {
                var contents = reader.ReadToEnd();

                if (!string.IsNullOrWhiteSpace(toBeReplaced))
                {
                    contents = contents.Replace(toBeReplaced, replacement ?? string.Empty);
                }

                this.fileSystem.File.WriteAllText(path, contents);
            }
        }

        private StreamReader GetResourceStreamReader(string nameOfResource)
        {
            return new StreamReader(this.GetResourceStream(nameOfResource));
        }

        private Stream GetResourceStream(string nameOfResource)
        {
            return this.GetType().Assembly.GetManifestResourceStream(nameOfResource);
        }

        protected void WriteImage(string folder, string filename)
        {
            string path = this.fileSystem.Path.Combine(folder, filename);

            using (Image image = Image.FromStream(this.GetResourceStream(this.namespaceOfResources + "img." + filename)))
            {
                using (var stream = this.fileSystem.File.Create(path))
                {
                    image.Save(stream, ImageFormat.Png);
                }
            }
        }

        protected void WriteScript(string folder, string filename)
        {
            string path = this.fileSystem.Path.Combine(folder, filename);

            using (var reader = this.GetResourceStreamReader(this.namespaceOfResources + "js." + filename))
            {
                this.fileSystem.File.WriteAllText(path, reader.ReadToEnd());
            }
        }

        protected void WriteFont(string folder, string filename)
        {
            using (var input = this.GetResourceStream(this.namespaceOfResources + "css.fonts." + filename))
            {
                using (var output = this.fileSystem.File.Create(this.fileSystem.Path.Combine(folder, filename)))
                {
                    CopyStream(input, output);
                }
            }
        }
    }
}


text:
import { strictEqual, truthy } from 'source/common/verify.js'
import { getRandomArrayBuffer, getRandomId62S } from 'source/common/math/random.js'
import { getSample } from 'source/common/math/sample.js'
import { isEqualArrayBuffer, concatArrayBuffer } from 'source/common/data/ArrayBuffer.js'
import {
  packArrayBufferChunk, parseArrayBufferChunk,
  uploadArrayBufferByChunk
} from './ChunkUpload.js'

const { describe, it, info = console.log } = globalThis

describe('Common.Module.ChunkUpload', () => {
  it('packArrayBufferChunk(),parseArrayBufferChunk()', async () => {
    const testChunkInfo = {
      chunkArrayBuffer: getRandomArrayBuffer(64),
      key: getRandomId62S(), chunkIndex: 0, chunkTotal: 1
    }
    const testPacket = await packArrayBufferChunk(testChunkInfo, true)
    const resultChunkInfo = await parseArrayBufferChunk(testPacket, true)

    truthy(isEqualArrayBuffer(testChunkInfo.chunkArrayBuffer, resultChunkInfo.chunkArrayBuffer))
    strictEqual(testChunkInfo.key, resultChunkInfo.key)
    strictEqual(testChunkInfo.chunkIndex, resultChunkInfo.chunkIndex)
    strictEqual(testChunkInfo.chunkTotal, resultChunkInfo.chunkTotal)
  })

  it('uploadArrayBufferByChunk()', async () => {
    const fragArrayBuffer = getRandomArrayBuffer(1234)
    const testArrayBuffer = concatArrayBuffer(getSample(() => fragArrayBuffer, 1234 * 5)) // bigger than 5MiB
    const resultChunkInfoList = []

    await uploadArrayBufferByChunk({
      arrayBuffer: testArrayBuffer, key: getRandomId62S(), isSkipVerifyHash: true,
      uploadChunk: async (arrayBufferPacket, { chunkArrayBuffer, key, chunkIndex, chunkTotal }) => {
        resultChunkInfoList.push(await parseArrayBufferChunk(arrayBufferPacket, true))
      },
      onProgress: (uploadedSize, totalSize) => info('upload', uploadedSize, totalSize)
    })

    const resultArrayBuffer = concatArrayBuffer(resultChunkInfoList.map(({ chunkArrayBuffer }) => chunkArrayBuffer))

    strictEqual(resultArrayBuffer.byteLength, 1234 * 1234 * 5)
    truthy(isEqualArrayBuffer(testArrayBuffer, resultArrayBuffer))
  })
})


text:
require 'test_helper'

class Aviator::Test

  describe 'aviator/openstack/identity/v2/admin/get_tenant_by_id' do

    def create_request(session_data = get_session_data, &block)
      block ||= lambda do |params|
                  params[:id] = 'this_doesnt_matter_with_this_test'
                end

      klass.new(session_data, &block)
    end

    def get_session_data
      session.send :auth_info
    end

    def helper
      Aviator::Test::RequestHelper
    end

    def klass
      @klass ||= helper.load_request('openstack', 'identity', 'v2', 'admin', 'get_tenant_by_id.rb')
    end

    def session
      unless @session
        @session = Aviator::Session.new(
          config_file: Environment.path,
          environment: 'openstack_admin'
        )
        @session.authenticate
      end

      @session
    end

    validate_attr :anonymous? do
      klass.anonymous?.must_equal false
    end

    validate_attr :api_version do
      klass.api_version.must_equal :v2
    end

    validate_attr :body do
      klass.body?.must_equal false
      create_request.body?.must_equal false
    end

    validate_attr :endpoint_type do
      klass.endpoint_type.must_equal :admin
    end

    validate_attr :headers do
      session_data = get_session_data

      headers = { 'X-Auth-Token' => session_data[:access][:token][:id] }

      request = create_request(session_data)

      request.headers.must_equal headers
    end

    validate_attr :http_method do
      create_request.http_method.must_equal :get
    end

    validate_attr :optional_params do
      klass.optional_params.must_equal []
    end

    validate_attr :required_params do
      klass.required_params.must_equal [:id]
    end

    validate_attr :url do
      session_data = get_session_data
      service_spec = session_data[:access][:serviceCatalog].find{|s| s[:type] == 'identity' }
      tenant_id    = 'itdoesnotmatter'
      url          = "#{ service_spec[:endpoints][0][:adminURL] }/tenants/#{ tenant_id }"

      request = create_request do |p|
        p[:id] = tenant_id
      end

      request.url.must_equal url
    end

    validate_response 'a valid tenant id is provided' do
      service = session.identity_service
      tenant  = session.identity_service.request(:list_tenants).body[:tenants].first

      response = service.request :get_tenant_by_id do |p|
        p[:id] = tenant[:id]
      end

      response.status.must_equal 200
      response.body.wont_be_nil
      response.body[:tenant][:id].must_equal tenant[:id]
      response.headers.wont_be_nil
    end

  end

end


text:
class StaticsController < ApplicationController
  def about
    @package_name = "Julia Observer"
    @package_description = "julia language package browser 🔎"

    @package_owner = "djsegal"
  end
end


text:
using Rabbit.Kernel.Extensions.Models;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace Rabbit.Kernel.Extensions
{
    /// <summary>
    /// 扩展条目。
    /// </summary>
    public class ExtensionEntry
    {
        /// <summary>
        /// 扩展描述符。
        /// </summary>
        public ExtensionDescriptorEntry Descriptor { get; set; }

        /// <summary>
        /// 扩展程序集。
        /// </summary>
        public Assembly Assembly { get; set; }

        /// <summary>
        /// 扩展导出类型集合。
        /// </summary>
        public IEnumerable<Type> ExportedTypes { get; set; }
    }
}


text:
let router = require('./router');

describe('Router', function() {
  describe('getViewName', function() {
    it('should work with location hash', function() {
      expect(router.getViewName('#foo')).toBe('foo');
    });
    it('should work with full url', function() {
      expect(router.getViewName('http://foo.bar/baz?tac=toe#foo')).toBe('foo');
    });
    it('should return default view otherwise', function() {
      expect(router.getViewName('foo')).toBe(router.views.default);
    });
  });

  describe('onRouteChange', function() {
    let originalQs, main;
    beforeAll(function() {
      originalQs = document.querySelector;
      document.querySelector = () => main;
    });
    beforeEach(function() {
      main = {innerHTML: ''};
      router.register('navigation', {
        loading: jest.fn()
      });
    });

    it('should execute view function', function() {
      router.views['mock'] = jest.fn();
      router.onRouteChange('mock');
      expect(router.views['mock']).toHaveBeenCalled();
    });
    it('should set main html', function() {
      let mockHTML = '<b>foo</b>';
      router.views['mock'] = function(callback) {
        callback(mockHTML);
      };
      router.onRouteChange('mock');
      expect(main.innerHTML).toBe(mockHTML);
    });
    it('should set loading state and then replace it', function(done) {
      let loadingHTML = router.views.loading();
      router.views['mock'] = function(callback) {
        setTimeout(() => {
          callback('foo');
          expect(main.innerHTML).toBe('foo');
          done();
        }, 0);
      };
      router.onRouteChange('mock');
      expect(main.innerHTML).toBe(loadingHTML);
    });

    afterAll(function() {
      document.querySelector = originalQs.bind(document);
    })
  });
});


text:
@class NSString;

@interface MPDesignerEventBindingResponseMesssage : MPAbstractABTestDesignerMessage
{
}

+ (id)message;
@property(copy, nonatomic) NSString *status;

@end


text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Formatting;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Formatting
{
    public class FormattingEngineMultiSpanTests : CSharpFormattingTestBase
    {
        [Fact, Trait(Traits.Feature, Traits.Features.Formatting)]
        public async Task EndOfLine()
        {
            var content = @"namespace A{/*1*/}/*2*/";
            var expected = @"namespace A{}";

            await AssertFormatAsync(content, expected);
        }

        [Fact, Trait(Traits.Feature, Traits.Features.Formatting)]
        public async Task Simple1()
            => await AssertFormatAsync("namespace A/*1*/{}/*2*/ class A {}", "namespace A{ } class A {}");

        [Fact, Trait(Traits.Feature, Traits.Features.Formatting)]
        public async Task DontFormatTriviaOutsideOfSpan_IncludingTrailingTriviaOnNewLine()
        {
            var content = @"namespace A
/*1*/{
        }/*2*/

class A /*1*/{}/*2*/";

            var expected = @"namespace A
{
}

class A { }";

            await AssertFormatAsync(content, expected);
        }

        [Fact, Trait(Traits.Feature, Traits.Features.Formatting)]
        public async Task FormatIncludingTrivia()
        {
            var content = @"namespace A
/*1*/{
        }   /*2*/

class A /*1*/{}/*2*/";

            var expected = @"namespace A
{
}

class A { }";

            await AssertFormatAsync(content, expected);
        }

        [Fact, Trait(Traits.Feature, Traits.Features.Formatting)]
        public async Task MergeSpanAndFormat()
        {
            var content = @"namespace A
/*1*/{
        }   /*2*/   /*1*/

class A{}/*2*/";

            var expected = @"namespace A
{
}

class A { }";

            await AssertFormatAsync(content, expected);
        }

        [Fact, Trait(Traits.Feature, Traits.Features.Formatting)]
        public async Task OverlappedSpan()
        {
            var content = @"namespace A
/*1*/{
     /*1*/   }   /*2*/

class A{}/*2*/";

            var expected = @"namespace A
{
}

class A { }";

            await AssertFormatAsync(content, expected);
        }

        [Fact]
        [WorkItem(554160, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/554160")]
        [Trait(Traits.Feature, Traits.Features.Formatting)]
        public async Task FormatSpanNullReference01()
        {
            var code = @"/*1*/class C
{
    void F()
    {
        System.Console.WriteLine();
    }
}/*2*/";

            var expected = @"class C
{
    void F()
    {
    System.Console.WriteLine();
    }
}";
            var changingOptions = new OptionsCollection(LanguageNames.CSharp)
            {
                { CSharpFormattingOptions2.IndentBlock, false }
            };
            await AssertFormatAsync(code, expected, changedOptionSet: changingOptions);
        }

        [Fact]
        [WorkItem(554160, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/554160")]
        [Trait(Traits.Feature, Traits.Features.Formatting)]
        public async Task FormatSpanNullReference02()
        {
            var code = @"class C/*1*/
{
    void F()
    {
        System.Console.WriteLine();
    }
}/*2*/";

            var expected = @"class C
{
    void F()
    {
        System.Console.WriteLine();
    }
}";
            var changingOptions = new OptionsCollection(LanguageNames.CSharp)
            {
                { CSharpFormattingOptions2.WrappingPreserveSingleLine, false }
            };
            await AssertFormatAsync(code, expected, changedOptionSet: changingOptions);
        }

        [WorkItem(539231, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539231")]
        [Fact, Trait(Traits.Feature, Traits.Features.Formatting)]
        public async Task EmptySpan()
        {
            using var workspace = new AdhocWorkspace();

            var project = workspace.CurrentSolution.AddProject("Project", "Project.dll", LanguageNames.CSharp);
            var document = project.AddDocument("Document", SourceText.From(""));

            var syntaxTree = await document.GetSyntaxTreeAsync();
            var result = Formatter.Format(await syntaxTree.GetRootAsync(), TextSpan.FromBounds(0, 0), workspace, cancellationToken: CancellationToken.None);
        }

        private Task AssertFormatAsync(string content, string expected, OptionsCollection changedOptionSet = null)
        {
            var tuple = PreprocessMarkers(content);

            return AssertFormatAsync(expected, tuple.Item1, tuple.Item2, changedOptionSet: changedOptionSet);
        }

        private static Tuple<string, List<TextSpan>> PreprocessMarkers(string codeWithMarker)
        {
            var currentIndex = 0;
            var spans = new List<TextSpan>();

            while (currentIndex < codeWithMarker.Length)
            {
                var startPosition = codeWithMarker.IndexOf("/*1*/", currentIndex, StringComparison.Ordinal);
                if (startPosition < 0)
                {
                    // no more markers
                    break;
                }

                codeWithMarker = codeWithMarker.Substring(0, startPosition) + codeWithMarker.Substring(startPosition + 5);

                var endPosition = codeWithMarker.IndexOf("/*2*/", startPosition, StringComparison.Ordinal);

                codeWithMarker = codeWithMarker.Substring(0, endPosition) + codeWithMarker.Substring(endPosition + 5);

                spans.Add(TextSpan.FromBounds(startPosition, endPosition));

                currentIndex = startPosition;
            }

            return Tuple.Create(codeWithMarker, spans);
        }
    }
}